package com.yixin.hospital.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.Constant;
import com.yixin.hospital.entity.bo.UserDeptWorkAddressJobOffice;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.drugdepository.DrugDepositoryAddReqDTO;
import com.yixin.hospital.entity.dto.req.drugdepository.DrugDepositoryEditReqDTO;
import com.yixin.hospital.entity.vo.DeptListDrugDepVO;
import com.yixin.hospital.entity.vo.DrugDepositoryVo;
import com.yixin.hospital.enums.DrugDepositoryOtpTypeEnum;
import com.yixin.hospital.service.*;
import com.yixin.hospital.utils.CaffeineUtils;
import com.yixin.hospital.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.yixin.hospital.common.Constant.USER_CACHE;
import static com.yixin.hospital.enums.ResponseCodeEnum.DEPT_DEPOSITORY_EXIT;

@RestController
@RequestMapping("/drug-depository")
@Api(value = "库房管理", tags = "库房管理")
public class DrugDepositoryController {

    @Resource
    DrugDepositoryService drugDepositoryService;
    @Resource
    DeptService deptService;
    @Resource
    UserService userService;
    @Resource
    DrugDepositoryUserAuthService drugDepositoryUserAuthService;
    @Resource
    DrugDepositoryDutyAuthService drugDepositoryDutyAuthService;

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 16; i++) {
            sb.append((char)(new Random().nextInt(123 - 97) + 97));
        }
        System.out.println(sb);
    }

    @GetMapping("/list")
    @ApiOperation(value = "库房列表")
    public ApiResult<?> list() {
        List<DrugDepository> list = drugDepositoryService.list();
        List<DrugDepositoryVo> resp = new ArrayList<>();
        for (DrugDepository drugDepository : list) {
            LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Dept::getId, drugDepository.getDept());
            Dept dept = deptService.getOne(queryWrapper);
            LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(User::getId, drugDepository.getManagerUserId());
            User user = userService.getOne(userWrapper);
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            BeanUtils.copyProperties(drugDepository, drugDepositoryVo);
            drugDepositoryVo.setDeptName(dept.getName());
            drugDepositoryVo.setManagerUserName(user.getName());
            resp.add(drugDepositoryVo);
        }
        return ApiResult.success(resp);
    }

    @PostMapping("/add")
    @ApiOperation(value = "添加库房")
    public ApiResult<?> add(@Valid @RequestBody DrugDepositoryAddReqDTO drugDepositoryAddReqDTO, HttpServletRequest request) {
        List<DrugDepository> list = drugDepositoryService.list(new LambdaQueryWrapper<DrugDepository>().eq(DrugDepository::getDept, drugDepositoryAddReqDTO.getDept()));
        if (!CollectionUtils.isEmpty(list)) return ApiResult.error(DEPT_DEPOSITORY_EXIT);

        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        DrugDepository drugDepository = new DrugDepository();
        BeanUtils.copyProperties(drugDepositoryAddReqDTO, drugDepository);

        drugDepository.setCreatedBy(userName);
        drugDepository.setUpdatedBy(userName);
        drugDepositoryService.save(drugDepository);
        return ApiResult.success();
    }

    @PutMapping("/edit")
    @ApiOperation(value = "编辑库房")
    public ApiResult<?> edit(@Valid @RequestBody DrugDepositoryEditReqDTO drugDepositoryEditReqDTO, HttpServletRequest request) {
//        List<DrugDepository> list = drugDepositoryService.list(new LambdaQueryWrapper<DrugDepository>().eq(DrugDepository::getDept, drugDepositoryEditReqDTO.getDept()));
//        if (!CollectionUtils.isEmpty(list)) {
//            return ApiResult.error(DEPT_DEPOSITORY_EXIT);
//        }
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        DrugDepository drugDepository = new DrugDepository();
        BeanUtils.copyProperties(drugDepositoryEditReqDTO, drugDepository);
        drugDepository.setUpdatedBy(userName);
        drugDepositoryService.updateById(drugDepository);
        return ApiResult.success();
    }

    @DeleteMapping("/remove/{id}")
    @ApiOperation(value = "删除库房")
    public ApiResult<?> remove(@PathVariable int id) {
        drugDepositoryService.removeById(id);
        return ApiResult.success();
    }

    @GetMapping("/dept-list/{deptId}")
    @ApiOperation(value = "部门及其下属部门库房列表")
    public ApiResult<?> deptList(@PathVariable Long deptId) {
//        List<Long> deptIds = new ArrayList<>();
//        deptIds.add(deptId);
//        getDeptAll(deptId, deptIds);
        // 从子部门所有库 改成 只查登录部门的库
        List<DrugDepository> list = drugDepositoryService.list(new LambdaQueryWrapper<DrugDepository>().in(DrugDepository::getDept, Arrays.asList(deptId)));
        List<DeptListDrugDepVO> deptListDrugDepVOS = BeanUtil.copyToList(list, DeptListDrugDepVO.class);
        for (DeptListDrugDepVO deptListDrugDepVO : deptListDrugDepVOS) {
            deptListDrugDepVO.setDeptName(deptService.getById(deptListDrugDepVO.getDept()).getName());
        }
        return ApiResult.success(deptListDrugDepVOS);
    }

    private void getDeptAll(Long deptId, List<Long> deptIds){
        List<Dept> deptList = deptService.list(new LambdaQueryWrapper<Dept>().eq(Dept::getPid, deptId));
        for (Dept dept : deptList) {
            deptIds.add(dept.getId());
            getDeptAll(dept.getId(), deptIds);
        }
    }

    @GetMapping("/available-list-optType")
    @ApiOperation(value = "可用库房列表")
    public ApiResult<List<DrugDepositoryVo>> availableList(HttpServletRequest request, @RequestParam Integer optType) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        List<DrugDepositoryUserAuth> userAuthList = drugDepositoryUserAuthService.list(new LambdaQueryWrapper<DrugDepositoryUserAuth>().eq(DrugDepositoryUserAuth::getUserId, userId).eq(DrugDepositoryUserAuth::getOptType, optType).orderByAsc(DrugDepositoryUserAuth::getDrugDepositoryId));
        Set<Long> jobUserAuthIdList = userAuthList.stream().map(DrugDepositoryUserAuth::getDrugDepositoryId).collect(Collectors.toSet());

        // 获取当前用户登录职务 有该操作权限
        List<UserDeptWorkAddressJobOffice> loginList = (List<UserDeptWorkAddressJobOffice>) CaffeineUtils.get(USER_CACHE);
        UserDeptWorkAddressJobOffice loginUser = loginList.stream().filter(u -> u.getUserId().equals(userId)).collect(Collectors.toList()).get(0);
        Long jobDutyId = loginUser.getJobDutyId();
        List<DrugDepositoryDutyAuth> JobDutyAuthList = drugDepositoryDutyAuthService.list(new LambdaQueryWrapper<DrugDepositoryDutyAuth>()
                .eq(DrugDepositoryDutyAuth::getJobDutyId, jobDutyId)
                .eq(DrugDepositoryDutyAuth::getOptType, optType));
        Set<Long> jobDutyAuthIdList = JobDutyAuthList.stream().map(DrugDepositoryDutyAuth::getDrugDepositoryId).collect(Collectors.toSet());
        List<Long> containsIds = jobUserAuthIdList.stream()
                .filter(jobDutyAuthIdList::contains)
                .collect(Collectors.toList());

        List<DrugDepositoryVo> resp = new ArrayList<>();
        for (Long drugDepositoryId : containsIds) {
            DrugDepository drugDepository = drugDepositoryService.getById(drugDepositoryId);
            DrugDepositoryVo drugDepositoryVo = new DrugDepositoryVo();
            BeanUtils.copyProperties(drugDepository, drugDepositoryVo);
            resp.add(drugDepositoryVo);
        }
        return ApiResult.success(resp);
    }

}
